package com.audaque.springboot.foshanupload.web.reactivedemo.processer;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * @author zgb
 * @desc ...
 * @date 2023-08-08 22:12:51
 */
@Slf4j
public class Processer implements Runnable {

    final Selector selector;
    final SocketChannel channel;

    public Processer(SocketChannel channel) throws IOException {
        //Reactor初始化
        selector = Selector.open();
        this.channel = channel;
        channel.register(selector,
                SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    }

    public void run() {
        try {
            while (!Thread.interrupted()) {
                selector.select();
                Set<SelectionKey> selected = selector.selectedKeys();
                Iterator<SelectionKey> it = selected.iterator();
                while (it.hasNext()) {
                    SelectionKey sk = it.next();
                    if (sk.isWritable()) {
                        ByteBuffer buffer = ByteBuffer.allocate(48);

                        Scanner scanner = new Scanner(System.in);
                        log.debug("请输入发送内容:");
                        if (scanner.hasNext()) {
                            SocketChannel socketChannel = (SocketChannel) sk.channel();
                            String next = scanner.next();
                            buffer.put(next.getBytes());
                            buffer.flip();
                            // 操作三：发送数据
                            socketChannel.write(buffer);
                            buffer.clear();
                        }

                    }
                  else  if (sk.isReadable()) {
                        // 若选择键的IO事件是“可读”事件,读取数据
                        SocketChannel socketChannel = (SocketChannel) sk.channel();

                        //读取数据
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        int length = 0;
                        while ((length = socketChannel.read(byteBuffer)) > 0) {
                            byteBuffer.flip();
                            log.debug("server echo:" + new String(byteBuffer.array(), 0, length));
                            byteBuffer.clear();
                        }

                    }
                    //处理结束了, 这里不能关闭select key，需要重复使用
                    //selectionKey.cancel();
                }
                selected.clear();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
